/**
 * 虚拟滚动管理器
 * 用于优化长列表渲染性能
 */
class VirtualScrollManager {
    /**
     * 构造函数
     * @param {Object} options 配置选项
     * @param {HTMLElement} options.container 容器元素
     * @param {Function} options.renderItem 渲染单个项目的函数
     * @param {number} options.itemHeight 项目高度估计值(px)
     * @param {number} options.overscan 可视区域外预渲染的项目数量
     * @param {Function} options.getItemKey 获取项目唯一键的函数
     */
    constructor(options) {
        this.container = options.container;
        this.renderItem = options.renderItem;
        this.itemHeight = options.itemHeight || 80;
        this.overscan = options.overscan || 5;
        this.getItemKey = options.getItemKey || (item => item.id);
        
        this.items = [];
        this.visibleItems = [];
        this.scrollTop = 0;
        this.containerHeight = 0;
        this.totalHeight = 0;
        this.visibleStartIndex = 0;
        this.visibleEndIndex = 0;
        
        // 创建内部元素
        this.createInternalElements();
        
        // 绑定滚动事件
        this.container.addEventListener('scroll', this.handleScroll.bind(this));
        
        // 创建ResizeObserver监听容器大小变化
        this.resizeObserver = new ResizeObserver(entries => {
            for (const entry of entries) {
                if (entry.target === this.container) {
                    this.containerHeight = entry.contentRect.height;
                    this.updateVisibleItems();
                }
            }
        });
        this.resizeObserver.observe(this.container);
    }
    
    /**
     * 创建内部元素
     */
    createInternalElements() {
        // 创建占位元素，用于保持滚动条高度
        this.placeholder = document.createElement('div');
        this.placeholder.style.position = 'absolute';
        this.placeholder.style.top = '0';
        this.placeholder.style.left = '0';
        this.placeholder.style.width = '1px';
        this.placeholder.style.visibility = 'hidden';
        
        // 创建内容容器
        this.content = document.createElement('div');
        this.content.style.position = 'relative';
        
        // 设置容器样式
        this.container.style.position = 'relative';
        this.container.style.overflow = 'auto';
        
        // 添加元素到容器
        this.container.appendChild(this.placeholder);
        this.container.appendChild(this.content);
    }
    
    /**
     * 处理滚动事件
     */
    handleScroll() {
        const newScrollTop = this.container.scrollTop;
        if (Math.abs(newScrollTop - this.scrollTop) > this.itemHeight / 3) {
            this.scrollTop = newScrollTop;
            this.updateVisibleItems();
        }
    }
    
    /**
     * 设置项目数据
     * @param {Array} items 项目数据数组
     */
    setItems(items) {
        this.items = items;
        this.totalHeight = items.length * this.itemHeight;
        this.placeholder.style.height = `${this.totalHeight}px`;
        this.updateVisibleItems();
    }
    
    /**
     * 添加项目
     * @param {Object} item 要添加的项目
     */
    addItem(item) {
        this.items.push(item);
        this.totalHeight = this.items.length * this.itemHeight;
        this.placeholder.style.height = `${this.totalHeight}px`;
        this.updateVisibleItems();
        
        // 如果添加的是新消息，滚动到底部
        if (this.shouldScrollToBottom) {
            this.scrollToBottom();
        }
    }
    
    /**
     * 更新可见项目
     */
    updateVisibleItems() {
        if (!this.items.length) return;
        
        this.containerHeight = this.container.clientHeight;
        
        // 计算可见项目的起始和结束索引
        const startIndex = Math.max(0, Math.floor(this.scrollTop / this.itemHeight) - this.overscan);
        const endIndex = Math.min(
            this.items.length - 1,
            Math.ceil((this.scrollTop + this.containerHeight) / this.itemHeight) + this.overscan
        );
        
        // 如果可见范围没有变化，不需要更新
        if (startIndex === this.visibleStartIndex && endIndex === this.visibleEndIndex) {
            return;
        }
        
        this.visibleStartIndex = startIndex;
        this.visibleEndIndex = endIndex;
        this.visibleItems = this.items.slice(startIndex, endIndex + 1);
        
        // 渲染可见项目
        this.renderVisibleItems();
    }
    
    /**
     * 渲染可见项目
     */
    renderVisibleItems() {
        // 清空内容容器
        this.content.innerHTML = '';
        
        // 渲染每个可见项目
        this.visibleItems.forEach((item, index) => {
            const actualIndex = this.visibleStartIndex + index;
            const itemElement = this.renderItem(item, actualIndex);
            
            // 设置项目位置
            itemElement.style.position = 'absolute';
            itemElement.style.top = `${actualIndex * this.itemHeight}px`;
            itemElement.style.width = '100%';
            
            // 添加到内容容器
            this.content.appendChild(itemElement);
        });
    }
    
    /**
     * 滚动到指定索引的项目
     * @param {number} index 项目索引
     */
    scrollToIndex(index) {
        const targetScrollTop = index * this.itemHeight;
        this.container.scrollTop = targetScrollTop;
    }
    
    /**
     * 滚动到底部
     */
    scrollToBottom() {
        this.container.scrollTop = this.totalHeight;
    }
    
    /**
     * 设置是否在添加新项目时自动滚动到底部
     * @param {boolean} value 是否自动滚动到底部
     */
    setAutoScrollToBottom(value) {
        this.shouldScrollToBottom = value;
    }
    
    /**
     * 销毁虚拟滚动管理器
     */
    destroy() {
        this.container.removeEventListener('scroll', this.handleScroll);
        this.resizeObserver.disconnect();
        this.container.innerHTML = '';
    }
}